home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / TEMP / GNU / bison / ErrorRecov < prev    next >
Text File  |  1995-06-28  |  5KB  |  122 lines

  1. Error Recovery
  2. Previous: <Algorithm=>Algorithm> * Next: <Context Dependency=>ContextDep> * Up: <Top=>!Root>
  3.  
  4. #Wrap on
  5. {fH2}Error Recovery{f}
  6.  
  7. It is not usually acceptable to have a program terminate on a parse
  8. error.  For example, a compiler should recover sufficiently to parse the
  9. rest of the input file and check it for errors; a calculator should accept
  10. another expression.
  11.  
  12. In a simple interactive command parser where each input is one line, it may
  13. be sufficient to allow {fCode}yyparse{f} to return 1 on error and have the
  14. caller ignore the rest of the input line when that happens (and then call
  15. {fCode}yyparse{f} again).  But this is inadequate for a compiler, because it
  16. forgets all the syntactic context leading up to the error.  A syntax error
  17. deep within a function in the compiler input should not cause the compiler
  18. to treat the following line like the beginning of a source file.
  19.  
  20. You can define how to recover from a syntax error by writing rules to
  21. recognize the special token {fCode}error{f}.  This is a terminal symbol that
  22. is always defined (you need not declare it) and reserved for error
  23. handling.  The Bison parser generates an {fCode}error{f} token whenever a
  24. syntax error happens; if you have provided a rule to recognize this token
  25. in the current context, the parse can continue.  
  26.  
  27. For example:
  28.  
  29. #Wrap off
  30. #fCode
  31. stmnts:  \/\* empty string \*\/
  32.         | stmnts '\\n'
  33.         | stmnts exp '\\n'
  34.         | stmnts error '\\n'
  35. #f
  36. #Wrap on
  37.  
  38. The fourth rule in this example says that an error followed by a newline
  39. makes a valid addition to any {fCode}stmnts{f}.
  40.  
  41. What happens if a syntax error occurs in the middle of an {fCode}exp{f}?  The
  42. error recovery rule, interpreted strictly, applies to the precise sequence
  43. of a {fCode}stmnts{f}, an {fCode}error{f} and a newline.  If an error occurs in
  44. the middle of an {fCode}exp{f}, there will probably be some additional tokens
  45. and subexpressions on the stack after the last {fCode}stmnts{f}, and there
  46. will be tokens to read before the next newline.  So the rule is not
  47. applicable in the ordinary way.
  48.  
  49. But Bison can force the situation to fit the rule, by discarding part of
  50. the semantic context and part of the input.  First it discards states and
  51. objects from the stack until it gets back to a state in which the
  52. {fCode}error{f} token is acceptable.  (This means that the subexpressions
  53. already parsed are discarded, back to the last complete {fCode}stmnts{f}.)  At
  54. this point the {fCode}error{f} token can be shifted.  Then, if the old
  55. look-ahead token is not acceptable to be shifted next, the parser reads
  56. tokens and discards them until it finds a token which is acceptable.  In
  57. this example, Bison reads and discards input until the next newline
  58. so that the fourth rule can apply.
  59.  
  60. The choice of error rules in the grammar is a choice of strategies for
  61. error recovery.  A simple and useful strategy is simply to skip the rest of
  62. the current input line or current statement if an error is detected:
  63.  
  64. #Wrap off
  65. #fCode
  66. stmnt: error ';'  \/\* on error, skip until ';' is read \*\/
  67. #f
  68. #Wrap on
  69.  
  70. It is also useful to recover to the matching close-delimiter of an
  71. opening-delimiter that has already been parsed.  Otherwise the
  72. close-delimiter will probably appear to be unmatched, and generate another,
  73. spurious error message:
  74.  
  75. #Wrap off
  76. #fCode
  77. primary:  '(' expr ')'
  78.         | '(' error ')'
  79.         …
  80.         ;
  81. #f
  82. #Wrap on
  83.  
  84. Error recovery strategies are necessarily guesses.  When they guess wrong,
  85. one syntax error often leads to another.  In the above example, the error
  86. recovery rule guesses that an error is due to bad input within one
  87. {fCode}stmnt{f}.  Suppose that instead a spurious semicolon is inserted in the
  88. middle of a valid {fCode}stmnt{f}.  After the error recovery rule recovers
  89. from the first error, another syntax error will be found straightaway,
  90. since the text following the spurious semicolon is also an invalid
  91. {fCode}stmnt{f}.
  92.  
  93. To prevent an outpouring of error messages, the parser will output no error
  94. message for another syntax error that happens shortly after the first; only
  95. after three consecutive input tokens have been successfully shifted will
  96. error messages resume.
  97.  
  98. Note that rules which accept the {fCode}error{f} token may have actions, just
  99. as any other rules can.
  100.  
  101. You can make error messages resume immediately by using the macro
  102. {fCode}yyerrok{f} in an action.  If you do this in the error rule's action, no
  103. error messages will be suppressed.  This macro requires no arguments;
  104. {fEmphasis}yyerrok;{f} is a valid C statement.
  105.  
  106. The previous look-ahead token is reanalyzed immediately after an error.  If
  107. this is unacceptable, then the macro {fCode}yyclearin{f} may be used to clear
  108. this token.  Write the statement {fEmphasis}yyclearin;{f} in the error rule's
  109. action.
  110.  
  111. For example, suppose that on a parse error, an error handling routine is
  112. called that advances the input stream to some point where parsing should
  113. once again commence.  The next symbol returned by the lexical scanner is
  114. probably correct.  The previous look-ahead token ought to be discarded
  115. with {fEmphasis}yyclearin;{f}.
  116.  
  117. The macro {fCode}YYRECOVERING{f} stands for an expression that has the
  118. value 1 when the parser is recovering from a syntax error, and 0 the
  119. rest of the time.  A value of 1 indicates that error messages are
  120. currently suppressed for new syntax errors.
  121.  
  122.